#include <iostream>
#include <list>
#include <set>
#include <math.h>
#include <sstream> 
#include <string>
#include <assert.h>
using namespace std;

#define forn(i,n) for(int i=0;i<n;i++)
#define forsn(i,s,n) for(int i=s;i<n;i++)
#define forall(it,X) for(typeof((X).begin()) it=(X).begin();it!=(X).end();it++)

#define belongs(X,e) (X).find(e)!=(X).end()
#define espar(n) (n%2==0)

typedef pair<int,int> ii;

/* Considero (i,j) como la posicion en el tablero */
/* Convencion: el cuadrado (0,0) siempre es blanco y esta en la esquina NE */

bool used_down[16];
bool used_up[16];

enum{ WHITE=0, BLACK };

int soluciones(int n, int k, int c, int si, int sj){
	if(k==0) return 1;
	if( si>=n ) return 0;

	int res = 0;
	forsn(i,si,n)
		for(int j=(i+c)%2;j<n;j+=2)
			if( !(i==si && j < sj ) && !(used_down[n-1-i+j]) && !(used_up[i+j]) ){
				used_down[n-1-i+j] = true;
				used_up[i+j] = true;

				int r = soluciones(n,k-1,c,i,j+2);
				res += r;

				used_down[n-1-i+j] = false;
				used_up[i+j] = false;
	}
	return res;
}

int main(){
	int n, k;
	forn(i,16) used_down[i] = false;
	forn(i,16) used_up[i] = false;

	while( cin >> n >> k && (n!=0 || k!=0) ){
		int res = 0;
		
		if(n==1 && k==1) res=1;
		else if(n==2 && k==2) res=4;
		else{

/* Si n=2k entonces hay (n-1)*n diagonales blancas y negras. Como mucho en cada color puede haber n-1 alfiles */
/* Si n=2k+1 entonces hay (n-1)*(n-1) negras y n*n blancas. Como mucho en el blanco pueden haber n fichas, y en el negro n-1 */

			int b_max = n-1;
			int w_max = espar(n) ? n-1 : n;

			if( k < b_max*w_max+1 ){
				int m = min(k,w_max);
				int w = m;
				int b = k - m;

				while( w >= 0 && b <= b_max ){
					int rw = soluciones(n,w,WHITE,0,0);
					int rb = soluciones(n,b,BLACK,0,1);
					res += rw*rb;
					w--; b++;		
				}
			}
		}
		cout << res << endl;
	}
	return 0;
}
